package math.functions;

import graphics.Graphable2D;
import graphics.GraphingProperties;

/**
 *
 * Fully Tested: No
 * Fully Documented: No
 * Created: 11-Dec-2011
 * Last Updated: 11-Dec-2011
 *
 * @author Shimu Wu
 */
public class RationalFunction implements Graphable2D {

    /**
     * A simple rational function of degree 1; f(x) = 1/x
     */
    public static final RationalFunction DEGREE_1 =
            new RationalFunction(Polynomial.CONSTANT,
            Polynomial.LINEAR);

    /**
     * A simple rational function of degree 2; f(x) = 1/x^2
     */
    public static final RationalFunction DEGREE_2 =
            new RationalFunction(Polynomial.CONSTANT,
            Polynomial.QUADRATIC);

    /**
     * A simple rational function of degree 3; f(x) = 1/x^3
     */
    public static final RationalFunction DEGREE_3 =
            new RationalFunction(Polynomial.CONSTANT,
            Polynomial.CUBIC);

    private Polynomial numerator, denominator;

    public RationalFunction(double[] numerator_coefficients,
            double[] denominator_coefficients) {
        this.numerator = new Polynomial(numerator_coefficients);
        this.denominator = new Polynomial(denominator_coefficients);
    }

    /**
     * Creates a rational function with the given polynomials as the numerator
     * and denominator.
     * 
     * @see Polynomial
     * @param numerator the numerator of the new rational function
     * @param denominator the denominator of the new rational function
     */
    public RationalFunction(Polynomial numerator,
            Polynomial denominator) {
        this.numerator = numerator;
        this.denominator = denominator;
    }

    public Polynomial getNumerator() {
        return numerator;
    }

    public Polynomial getDenominator() {
        return denominator;
    }

    public Double evaluate(Double x) {

        double numeratorSum = numerator.evaluate(x);
        double denominatorSum = denominator.evaluate(x);

        if (denominatorSum != 0) {
            return (numeratorSum / denominatorSum);
        } else {
            return (Double) null;
        }
    }

    public GraphingProperties getGraphProperties() {
        return new GraphingProperties();
    }
}

/*

procedure DrawAsymptote

    loop

        AY1 = AY2 + ScreenY div 40

        Draw.ThickLine ((int)((x + xMin) * xMagnification), AY1, (int)((x + xMin) * xMagnification), AY2, AWidth, AColour)

        AY2 = AY1 + ScreenY div 40

        exit when AY2 >= ScreenY

    end loop

    AY1 = 0
    AY2 = 0

end DrawAsymptote
*/